﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Chaina.Data;
using NHibernate;
using NHibernate.Criterion;

namespace Chaina.Data
{
    public abstract class DataAccessObject<Entity, IdType> : IDao<Entity, IdType>
    {
        public Entity GetByID(IdType ID)
        {
            ISession session = SessionFactory.Current.OpenSession();
            return session.Get<Entity>(ID); 
        }

        public List<Entity> GetAll()
        {
            return GetByCriteria();
        }

        protected List<Entity> GetByCriteria() 
        { 
            ISession session = SessionFactory.Current.OpenSession();
            ICriteria criteria = session.CreateCriteria(typeof(Entity)); 
            
            return criteria.List().Cast<Entity>().ToList(); 
        }

        public List<Entity> GetByExample(Entity exampleInstance, IList<string> propertiesToExclude)
        {
            ISession session = SessionFactory.Current.OpenSession();
            ICriteria criteria = session.CreateCriteria(typeof(Entity));
            Example example = Example.Create(exampleInstance);

            foreach (string propertyToExclude in propertiesToExclude) 
            { 
                example.ExcludeProperty(propertyToExclude); 
            }
            
            criteria.Add(example);

            return criteria.List().Cast<Entity>().ToList();
        }

        public Entity SaveOrUpdate(Entity entity)
        {
            ISession session = SessionFactory.Current.OpenSession(); 
            session.SaveOrUpdate(entity); 
            return entity;
        }

        public void Delete(Entity entity)
        {
            ISession session = SessionFactory.Current.OpenSession();
            session.Delete(entity);
        }
    }
}
